#ifndef _AFFECTOR_H_
#define _AFFECTOR_H_
#include "gDefine.h"
#include "CombatDef.h"
#include "EventArgs.h"
#include "MgrBase.h"
#include "SimpleRefection.h"
#include "CombatCard.h"
class CombatObj;
struct EventArgBase;
class Formula;
enum EAffactor
{
	EAffactor_MeleeAttack=0,
	EAffector_AtkModifyer,	
	EAffector_HpModifyer,
	EAffector_PushTarget,
	EAffector_EstimateModifyer,
	EAffector_DamageModifyer,
	EAffector_DoSkillDamage,
	EAffector_AddBuff,
	EAffector_ResoteHpByDamage_Discarded,
	EAffector_RemoveReactorSelf,
	EAffector_TargetReSelector,
	EAffector_DispelBuff,
	EAffector_SpModifyer,
	EAffector_DestroyCard,
	EAffector_SummonCard,
	EAffector_ReverseCards,
	EAffector_LockEnemyTomb,
	EAffector_NUM,
};
class StringRow;
class AffectorBase
{
public:
	AffectorBase(EAffactor eAffector)
		:m_eAffector(eAffector)
	{
	}
	virtual AffectorBase::~AffectorBase(){	}
	virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const=0;
	static const char* MakeArchieveName(int32 iAffectorID) 
	{   
		static char szPath[255];
		_snprintf_s(szPath,255,"../../config/Affector%02d.xml",iAffectorID);
		return szPath;
	}
	
protected:
	EAffactor m_eAffector;
	int32 CalBaseValue(Reactor *pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,ECalBaselValueType eType) const;

	double EvaluateFormula( const Formula * pFormula,Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target) const ;
private:
	
	
};

#define DECL_AFFECTOR(AFFECTOR,id)public: AFFECTOR():AffectorBase(id){};static const EAffactor AffectID=id;

class Affector_MeleeAttackTarget: public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_MeleeAttackTarget,EAffactor_MeleeAttack);
	DECL_REFLECTION(Affector_MeleeAttackTarget,MakeArchieveName(AffectID));
	
public:

	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	
	int32 m_iID;
	std::string m_sDisplayName;
	
	double	m_fDmgAddAddPercent;
	int32	m_iDmgAddValue;

	double m_fSubDmgAddPercent;
	int32 m_iSubDmgAddValue;
	bool	m_bAffectSp;
	rewrite  virtual void OnArchieveReaded(){}
};

class Affector_AtkModifyer:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_AtkModifyer,EAffector_AtkModifyer);
	DECL_REFLECTION(Affector_AtkModifyer,MakeArchieveName(AffectID));
public:

	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	
	int32	m_iID;
	std::string m_sDisplayName;
	EEventCounter m_eAddToCounter;
	bool m_bTempModify;
	int32 m_iFormula;

	Formula * m_pForumal;

	rewrite  virtual void OnArchieveReaded();
};

class Affector_HpModifyer:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_HpModifyer,EAffector_HpModifyer);
	DECL_REFLECTION(Affector_HpModifyer,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	
	int32	m_iID;
	std::string m_sDisplayName;
	EEventCounter m_eAddToCounter;
	bool m_bAddHpMax;
	int32 m_iFormula;
	bool	m_bAffectSp;
	rewrite  virtual void OnArchieveReaded();
	Formula * m_pFormula;
};

class Affector_PushTo:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_PushTo,EAffector_PushTarget);
	DECL_REFLECTION(Affector_PushTo,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	

	int32	m_iID;
	std::string m_sDisplayName;
	ECardStorage m_eDestination;
	rewrite  virtual void OnArchieveReaded(){}
};

class Affector_EstimateModifyer:public ReflectionBase,public AffectorBase	
{
	DECL_AFFECTOR(Affector_EstimateModifyer,EAffector_EstimateModifyer);
	DECL_REFLECTION(Affector_EstimateModifyer,MakeArchieveName(AffectID));
public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	

	int32	m_iID;
	std::string m_sDisplayName;
	EEstimateResult m_eResult;
	rewrite  virtual void OnArchieveReaded(){}
};

class Affector_DamageModifyer:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_DamageModifyer,EAffector_DamageModifyer);
	DECL_REFLECTION(Affector_DamageModifyer,MakeArchieveName(AffectID));
public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	

	int32	m_iID;
	std::string m_sDisplayName;
	int32 m_iAddFormula;
	int32 m_iSetFormula;

	rewrite  virtual void OnArchieveReaded();
	Formula * m_pAddFormula;
	Formula * m_pSetFormula;
};

class Affector_DoSkillDamage:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_DoSkillDamage,EAffector_DoSkillDamage);
	DECL_REFLECTION(Affector_DoSkillDamage,MakeArchieveName(AffectID));
public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	

	int32	m_iID;
	std::string m_sDisplayName;
	EDamageType m_eDamageType;
	EEventCounter m_eDmgAddToCounter;
	int32 m_iFormula;
	bool	m_bAffectSp;
	

	rewrite  virtual void OnArchieveReaded();
	Formula * m_pFormula;
};

class Affector_AddBuff:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_AddBuff,EAffector_AddBuff);
	DECL_REFLECTION(Affector_AddBuff,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	
	rewrite  virtual void OnArchieveReaded(){}

	int32	m_iID;
	std::string m_sDisplayName;
	double m_fRate;
	int32 m_iBuffID;
};

class TSkillValidators;
class Affector_DispelBuff:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_DispelBuff,EAffector_DispelBuff);
	DECL_REFLECTION(Affector_DispelBuff,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;

	rewrite  virtual void OnArchieveReaded();

	int32	m_iID;
	std::string m_sDisplayName;
	int32	m_iSkillValidator;

	TSkillValidators* m_pSkillValidator;
};

class Affector_RemoveReactorSelf:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_RemoveReactorSelf,EAffector_RemoveReactorSelf);
	DECL_REFLECTION(Affector_RemoveReactorSelf,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	
	int32	m_iID;
	std::string m_sDisplayName;
	int32 m_iDummy;
	rewrite  virtual void OnArchieveReaded(){}
};

class Selector;
class Affector_TargetReSelector:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_TargetReSelector,EAffector_TargetReSelector);
	DECL_REFLECTION(Affector_TargetReSelector,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;

	int32	m_iID;
	std::string m_sDisplayName;
	int32 m_iSelectorID;
	Selector * m_pSelector;
	rewrite  virtual void OnArchieveReaded();
};

class Affector_SPModifyer:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_SPModifyer,EAffector_SpModifyer);
	DECL_REFLECTION(Affector_SPModifyer,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;

	int32	m_iID;
	std::string m_sDisplayName;
	int32 m_iFormula;
	rewrite  virtual void OnArchieveReaded();
	Formula * m_pFormula;
};

class Affector_DestroyCard:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_DestroyCard,EAffector_DestroyCard);
	DECL_REFLECTION(Affector_DestroyCard,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;

	int32	m_iID;
	std::string m_sDisplayName;
	EEventCounter m_eHpMaxAddToCounter;
	EEventCounter m_eAtkAddToCounter;
	rewrite  virtual void OnArchieveReaded(){}
};

class Affector_SummonCard:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_SummonCard,EAffector_SummonCard);
	DECL_REFLECTION(Affector_SummonCard,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;

	rewrite  virtual void OnArchieveReaded(){};

	int32	m_iID;
	std::string m_sDisplayName;
	bool m_bCopySummonTarget;
	int32 m_iSummonCardDef;
	float m_fHpReservedPercent;
	float m_fAtkReservedPercent;
	ECardStorage m_eDestination;
	bool m_bActiveNow;
	bool m_bSummonWeak;
};

class Affector_ReverseCards:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_ReverseCards,EAffector_ReverseCards);
	DECL_REFLECTION(Affector_ReverseCards,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	rewrite  virtual void OnArchieveReaded(){};

	int32	m_iID;
	std::string m_sDisplayName;
	bool	m_bOurSide;
	ECardReorderType m_eReorderType;
};

class Affector_TombLockModifier:public ReflectionBase,public AffectorBase
{
	DECL_AFFECTOR(Affector_TombLockModifier,EAffector_LockEnemyTomb);
	DECL_REFLECTION(Affector_TombLockModifier,MakeArchieveName(AffectID));

public:
	rewrite virtual void Process(Reactor * pReactor,EventArgBase& rEvent,CombatObj * src,CombatObj * target,std::vector<CombatCard*>& vPendingMoveToTombCards) const;
	rewrite  virtual void OnArchieveReaded(){};
	int32	m_iID;
	std::string m_sDisplayName;
	bool   m_bOurSide;
	int32  m_iAddLock;
};
#endif